package com.hjl.sr.remoting;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;

import org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration;
import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;
import org.springframework.remoting.support.RemoteInvocationResult;

import com.hjl.sr.remoting.adaptor.JavaHttpClient;
import com.hjl.sr.security.Encrypter;

/**
 * @author pister
 * 2012-12-17 下午08:36:08
 */
public class SecuritySimpleHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor {
	
	private Encrypter encrypter;
	
	public SecuritySimpleHttpInvokerRequestExecutor(Encrypter encrypter) {
		super();
		this.encrypter = encrypter;
	}

	protected RemoteInvocationResult doExecuteRequest(
			HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
			throws IOException, ClassNotFoundException {
		try {
			HttpURLConnection con = openConnection(config);
			con.setReadTimeout(5 * 1000);
			con.setConnectTimeout(5 * 1000);

			EncryptContextHolder.setEncryptContext(new HttpClientEncryptContext(new JavaHttpClient(con)));
			
			prepareConnection(con, baos.size());
			writeRequestBody(config, con, baos);
			validateResponse(config, con);
			InputStream responseBody = readResponseBody(config, con);
	
			return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
		} finally {
			EncryptContextHolder.clearEncryptContext();
		}
	}
	
	@Override
	protected InputStream decorateInputStream(InputStream is) throws IOException {
		return encrypter.decryptInputStream(is, EncryptContextHolder.getEncryptContext());
	}

	@Override
	protected OutputStream decorateOutputStream(OutputStream os) throws IOException {
		return encrypter.encryptOutputStream(os, EncryptContextHolder.getEncryptContext());
	}



}
